using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using T.FAS.Runtime.DataAccess.SPI;
using T.FAS.Runtime.DataAccess.Service;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.DataModel.Dao;
using T.FAS.Runtime.DataAccess.ShardingRule;
using T.FAS.Runtime.DataAccess.SQLDom;
using T.FAS.Runtime.DataAccess.Common;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataModel.Plugin;
using T.FAS.Runtime.DataAccess.Engine;
using System.Threading;
using AppContext = T.ServiceComponent.Session.Service.AppContext;
using Newtonsoft.Json.Linq;

namespace T.FAS.Runtime.DataAccess.UnitTest
{
    [TestClass]
    public class CDOEngineTestWithSM
    {
        private readonly ChangeSetService _changeService = new ChangeSetService();

        [TestMethod]
        public void TestSaveUserRequirement()
        {
            try
            {
                var cdo = TestTool.GetMetaData<CompositeDataObject>("CDO_DO_DEP_UserRequirementWithNoFK", "PresetData", "UserRequirementJson");
                //数据库连接本地TestDatabase
                var @do = TestTool.GetMetaData<DataObject>("DO_DEP_UserRequirement", "PresetData", "UserRequirementJson");
                cdo.BuildModelObjectRelation();
                cdo.RootCompositeNodeObject.DataObject = @do;
                cdo.RootCompositeNodeObject.Associations.ForEach(asso =>
                {
                    if (asso.AssociateType == AssociateType.OuterLeftJoin)
                    {
                        asso.AssoDataObject = new DataObject();
                    }
                });
                TRecord obj = TestTool.ConstructTRecordBy("UserRequirementData_Create", "PresetData", "DataJson");
                try
                {
                    UnifiedDataAccessServiceFactory.GetInstance().DeleteDataSetForCDO(cdo, new List<string> { "9df7b240-1303-46c5-b3f6-6d2d1c3aabdc" });
                }
                catch
                {
                }

                TResult tResult = UnifiedDataAccessServiceFactory.GetInstance().SaveDataForCDO(cdo, obj);
                var tRecord = ((TCommonResult<TRecord>)tResult).Record;
            }
            catch (Exception e)
            {

                throw;
            }
        }

        [TestMethod]
        public void TestUpdateWithStatemachine()
        {
            //DebugSetting.IsDebug = true;
            Dictionary<string, object> exrParams = new Dictionary<string, object>
                    {
                        {"IsBatchUpdate", true }
                    };
            try
            {
                TestSaveUserRequirement(); //预置数据
                var cdo = TestTool.GetMetaData<CompositeDataObject>("CDO_DO_DEP_UserRequirementWithNoFK", "PresetData", "UserRequirementJson");
                //数据库连接本地TestDatabase
                var @do = TestTool.GetMetaData<DataObject>("DO_DEP_UserRequirement", "PresetData", "UserRequirementJson");
                cdo.BuildModelObjectRelation();
                cdo.RootCompositeNodeObject.DataObject = @do;
                cdo.RootCompositeNodeObject.Associations.ForEach(asso =>
                {
                    if (asso.AssociateType == AssociateType.OuterLeftJoin)
                    {
                        asso.AssoDataObject = new DataObject();
                    }
                });
                cdo.RootCompositeNodeObject.Elements.ForEach(ele =>
                {
                    if (ele.ElementType == ElementType.Normal)
                    {
                        ele.DataColumn = @do.Columns.FirstOrDefault(col => col.ID == ele.DataColumnID);
                    }
                });
                //9df7b240-1303-46c5-b3f6-6d2d1c3aabdc
                TRecord obj = TestTool.ConstructTRecordBy("UserRequirementData_Update", "PresetData", "DataJson");
                var oldVal = obj.GetValue("Code").ToString();
                obj.SetValue("Code", "yennefer");
                //第一次更新，获取变更日志
                var change1 = _changeService.GetChangeSet(cdo, ChangeSetType.Update, obj);
                var result = UnifiedDataAccessServiceFactory.GetInstance().UpdateDataForCDO(cdo, obj, exrParams) as TCommonResult<TRecord>;
                var newResult = UnifiedDataAccessServiceFactory.GetInstance().QueryDataForCDO(cdo, "9df7b240-1303-46c5-b3f6-6d2d1c3aabdc", exrParams) as TCommonResult<TRecord>;
                var newVal = newResult.Record.GetValue("Code").ToString();
                Assert.IsTrue(newVal == oldVal);
            }
            catch (Exception e)
            {

                throw;
            }
        }


        [TestMethod]
        public void TestUpdateWithStatemachinePrecondition()
        {
            CompositeDataObject cdo = null;
            Dictionary<string, object> exrParams = null;
            try
            {
                #region 初始化设置
                //DebugSetting.IsDebug = true;
                exrParams = new Dictionary<string, object>
                    {
                        {"IsBatchUpdate", true }
                    };
                TestSaveUserRequirement(); //预置数据
                #endregion

                #region 初始化元数据
                cdo = TestTool.GetMetaData<CompositeDataObject>("CDO_DO_DEP_UserRequirementWithNoFK", "PresetData", "UserRequirementJson");
                //数据库连接本地TestDatabase
                var @do = TestTool.GetMetaData<DataObject>("DO_DEP_UserRequirement", "PresetData", "UserRequirementJson");
                cdo.BuildModelObjectRelation();
                cdo.RootCompositeNodeObject.DataObject = @do;
                cdo.RootCompositeNodeObject.Associations.ForEach(asso =>
                {
                    if (asso.AssociateType == AssociateType.OuterLeftJoin)
                    {
                        asso.AssoDataObject = new DataObject();
                    }
                });
                cdo.RootCompositeNodeObject.Elements.ForEach(ele =>
                {
                    if (ele.ElementType == ElementType.Normal)
                    {
                        ele.DataColumn = @do.Columns.FirstOrDefault(col => col.ID == ele.DataColumnID);
                    }
                });
                #endregion

            }
            catch (Exception e)
            {

                throw;
            }
            //状态机id：e669cd01-8b59-4147-ab84-ab1e2e8a262b
            //单据id：9df7b240-1303-46c5-b3f6-6d2d1c3aabdc

            TRecord record = TestTool.ConstructTRecordBy("UserRequirementData_Update", "PresetData", "DataJson");
            record.SetValue("Code", "yennefer");
            try
            {
                //第一次更新，获取变更日志
                var change1 = _changeService.GetChangeSet(cdo, ChangeSetType.Update, record);
                var result = UnifiedDataAccessServiceFactory.GetInstance().UpdateDataForCDO(cdo, record, exrParams) as TCommonResult<TRecord>;
            }
            catch (Exception e)
            {
                Assert.IsTrue(e.Message.Contains("不满足事件:已接收的前置表达式条件，不允许保存"));
            }

            record.SetValue("Name", "aaa");
            var change2 = _changeService.GetChangeSet(cdo, ChangeSetType.Update, record);
            var result2 = UnifiedDataAccessServiceFactory.GetInstance().UpdateDataForCDO(cdo, record, exrParams) as TCommonResult<TRecord>;
        }
    }
}
